package sdmaker.parser;

import java.util.ArrayList;
import java.util.List;

import javax.swing.text.FlowView.FlowStrategy;

import fsa.State;

public class SetStateData {
	private List<StateData> stateDataList;
	private StateData lastAdded;

	
	
	/* ************************ *
	 * ***** CONSTRUCTORS ***** *
	 * ************************ */
	
	public SetStateData(){
		stateDataList= new ArrayList<StateData>();
		lastAdded=null;
	}

	public SetStateData(List<State> stateList){
		this();
		for(State state : stateList){
			this.stateDataList.add(StateData.getStateData(state));
		}
	}

	
	
	/* ************************ *
	 * ******** GETTERS ******* *
	 * ************************ */
	
	public StateData get(int index){
		StateData stateData= null;

		if(0 <= index && index < size()){
			stateData= stateDataList.get(index);
		}

		return stateData;
	}

	public StateData firstNotFullParsedFIFO(SetStateData forbiddenStates){
		StateData firstNotFull=null;

		for(int i= 0; i < stateDataList.size(); i++){
			if(stateDataList.get(i).fullParsed(forbiddenStates)==false){
				firstNotFull= stateDataList.get(i);
				break;
			}
		}

		return firstNotFull;
	}

	public StateData getLastAdded(){
		return lastAdded;
	}
	
	public int size(){
		return stateDataList.size();
	}
	
	
	public List<StateData> getStates(){
		return stateDataList;
	}

	
	
	/* ********************************* *
	 * **** SETTERS/ADDERS/REMOVERS **** *
	 * ********************************* */
	
	public SetStateData add(StateData stateData){
		boolean alreadyHere= false;

		for(StateData tmp : stateDataList){
			if(tmp.equals(stateData)){
				alreadyHere=true;
				break;
			}
		}

		if(alreadyHere==false){
			stateDataList.add(stateData);
		}

		lastAdded=stateData;
		
		return this;
	}

	public void addAll(SetStateData stateSet){
		stateDataList.addAll(stateSet.getStates());
	}
	
	public void remove(StateData stateData){
		int i= 0;

		if(contains(stateData)){
			for(i= 0; i < stateDataList.size(); i++){
				if(stateData.equals(stateDataList.get(i))){
					break;
				}
			}

			stateDataList.remove(i);
		}
	}

	public void removeAll(){
		stateDataList= new ArrayList<StateData>();
	}


	
	/* ************************ *
	 * ******* TESTERS ******** *
	 * ************************ */
	
	public boolean equals(SetStateData otherSet){
		return (this.contains(otherSet)&&otherSet.contains(this));
	}
	
	public Boolean contains(StateData stateData){
		Boolean contains= false;

		for(StateData tmp : stateDataList){
			if(tmp.equals(stateData)){
				contains= true;
				break;
			}
		}

		return contains;
	}

	public boolean contains(SetStateData stateDatas){
		boolean contains= true;

		for(int i= 0; i < stateDatas.size(); i++){
			if(contains(stateDatas.get(i))==false){
				contains= false;
				break;

			}
		}

		return contains;
	}

	
	
	/* ************************ *
	 * ******** OTHERS ******** *
	 * ************************ */
	
	public SetStateData intersection(SetStateData otherSet){
		SetStateData intersection= new SetStateData();

		for(StateData stateData : stateDataList){
			if(otherSet.contains(stateData)){
				intersection.add(stateData);
			}
		}

		return intersection;
	}
	
	public SetStateData union(SetStateData otherSet){
		SetStateData union= new SetStateData();
		
		union.addAll(this);
		union.addAll(otherSet);
		
		return union;
	}
	
	public SetStateData union(StateData stateData ){
		SetStateData union= new SetStateData();
		
		union.addAll(this);
		union.add(stateData);
		
		return union;
	}
	
	public SetStateData difference(SetStateData otherSet){
		SetStateData difference= new SetStateData();
		
		for(StateData stateData : stateDataList){
			if(otherSet.contains(stateData)==false){
				difference.add(stateData);
			}
		}
		
		return difference;
	}

	public String toString(){
		return stateDataList.toString();
	}
}
